package com.atguigu.gmall.oauth.service.impl;

import com.atguigu.gmall.common.util.IpUtil;
import com.atguigu.gmall.oauth.service.LoginService;
import com.atguigu.gmall.oauth.util.AuthToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.servlet.http.HttpServletRequest;
import java.util.Base64;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/***
 * 登录操作的业务层接口的实现类
 */
@Service
public class LoginServiceImpl implements LoginService {

    @Value("${auth.clientId}")
    private String clientId;
    @Value("${auth.clientSecret}")
    private String clientSecret;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private HttpServletRequest httpServletRequest;


    /**
     * 用户登录，获取到令牌
     *  @param username
     * @param password
     * @return
     */
    @Override
    public AuthToken login(String username, String password) {
        //1 拼接请求参数
        //获取微服务的动态地址
        ServiceInstance serviceInstance = loadBalancerClient.choose("service-oauth");
        //ip:port
        String uri = serviceInstance.getUri().toString();
        String url = uri + "/oauth/token";

        //1.1 声明一个请求头对象
        HttpHeaders httpHeaders = new HttpHeaders();
        httpHeaders.set("Authorization",this.getHeaderParam());

        //1.2 声明一个请求体map
        HttpHeaders bodyMap = new HttpHeaders();
        bodyMap.set("username",username);
        bodyMap.set("password",password);
        bodyMap.set("grant_type","password");

        HttpEntity entity = new HttpEntity(bodyMap,httpHeaders);

        //2 发送post请求
        /**
         * 1.请求的地址
         * 2.请求方式
         * 3.请求参数
         * 4.返回的类型
         */
        ResponseEntity<Map> responseEntity = restTemplate.exchange(url, HttpMethod.POST, entity, Map.class);

        //3 获取到响应的数据
        Map<String,String> body = responseEntity.getBody();
        //把结果封装成AuthToken对象
        AuthToken authToken = new AuthToken();
        authToken.setAccessToken(body.get("access_token"));
        authToken.setRefreshToken(body.get("refresh_token"));
        authToken.setJti(body.get("jti"));

        //获取ip地址
        String ipAddress = IpUtil.getIpAddress(httpServletRequest);
        //4 用户登录成功，将token存入redis中，与ip绑定
        stringRedisTemplate.opsForValue().set(ipAddress,body.get("access_token"));
        //设置有效时间
        stringRedisTemplate.expire(ipAddress,60*60*24, TimeUnit.SECONDS);

        //登录成功，同步购物车-TODO - feign调用 -MQ

        //登录成功，把购物车的内容写入redis中 -TODO - feign调用 -MQ

        //5 返回结果
        return authToken;
    }

    /**
     * 获取到请求头中 客户端id：客户端密码 ，的密文
     * @return
     */
    private String getHeaderParam() {
        String str = clientId + ":" + clientSecret;
        byte[] encode = Base64.getEncoder().encode(str.getBytes());
        return "Basic " + new String(encode);
    }

    /**
     * 测试
     * @param args
     */
    public static void main(String[] args) {
        byte[] decode = Base64.getDecoder().decode("");
        System.out.println(new java.lang.String(decode));
    }
}
